/*
 * Copyright (c) 2020, Sensirion AG
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * * Neither the name of Sensirion AG nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * \file
 *
 * \brief Sensirion SHT driver interface
 *
 * This module provides access to the SHT functionality over a generic I2C
 * interface. It supports measurements without clock stretching only.
 */

#ifndef __BSP_SHT4X_H__
#define __BSP_SHT4X_H__

#include <stdint.h>
#include <stdlib.h>



#ifdef __cplusplus
extern "C" {
#endif

//#define SHT4X_USE_SW_I2C    //使用软件模拟I2C
#define SHT4X_USE_HW_I2C    //使用硬件I2C


/* 
    SHT4X IIC 从机地址定义 
    SHT4X-AD1B : 0x44
    SHT4X-BD1B : 0x45
*/
#define SHT4X_ADDRESS           0x44

/* all measurement commands return T (CRC) RH (CRC) */
#define SHT4X_CMD_MEASURE_HPM   0xFD
#define SHT4X_CMD_MEASURE_LPM   0xE0
#define SHT4X_CMD_READ_SERIAL   0x89
#define SHT4X_CMD_DURATION_USEC 1000

/* 状态返回值 */
#define STATUS_OK               (0)
#define STATUS_ERR_BAD_DATA     (-1)
#define STATUS_CRC_FAIL         (-2)
#define STATUS_UNKNOWN_DEVICE   (-3)
#define STATUS_FAIL             (-4)
#define NO_ERROR                (0)


#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
#endif

#define CRC8_POLYNOMIAL     0x31
#define CRC8_INIT           0xFF
#define CRC8_LEN            1

#define SENSIRION_COMMAND_SIZE      2
#define SENSIRION_WORD_SIZE         2
#define SENSIRION_NUM_WORDS(x) (sizeof(x) / SENSIRION_WORD_SIZE)
#define SENSIRION_MAX_BUFFER_WORDS 32

/* 测量默认时间定义 */
#define SHT4X_MEASUREMENT_DURATION_USEC     10000   /* 10ms "high repeatability" */
#define SHT4X_MEASUREMENT_DURATION_LPM_USEC 2500    /* 2.5ms "low repeatability" */

typedef struct __sht4xval
{
    float       fTemp;
    float       fHumi;
    int16_t     iTemp;
    uint16_t    uiHumi;
}sht4xValTypeDef_t;


//--------------------------------------------------------------------------------//


/**
 * Detects if a sensor is connected by reading out the ID register.
 * If the sensor does not answer or if the answer is not the expected value,
 * the test fails.
 *
 * @return 0 if a sensor was detected
 */
int16_t sht4x_probe(void);

/**
 * Starts a measurement and then reads out the results. This function blocks
 * while the measurement is in progress. The duration of the measurement depends
 * on the sensor in use, please consult the datasheet.
 * Temperature is returned in [degree Celsius], multiplied by 1000,
 * and relative humidity in [percent relative humidity], multiplied by 1000.
 *
 * @param temperature   the address for the result of the temperature
 * measurement
 * @param humidity      the address for the result of the relative humidity
 * measurement
 * @return              0 if the command was successful, else an error code.
 */
int16_t sht4x_measure_blocking_read(int32_t* temperature, int32_t* humidity);

/**
 * Starts a measurement in high precision mode. Use sht4x_read() to read out the
 * values, once the measurement is done. The duration of the measurement depends
 * on the sensor in use, please consult the datasheet.
 *
 * @return     0 if the command was successful, else an error code.
 */
int16_t sht4x_measure(void);

/**
 * Reads out the results of a measurement that was previously started by
 * sht4x_measure(). If the measurement is still in progress, this function
 * returns an error.
 * Temperature is returned in [degree Celsius], multiplied by 1000,
 * and relative humidity in [percent relative humidity], multiplied by 1000.
 *
 * @param temperature   the address for the result of the temperature
 * measurement
 * @param humidity      the address for the result of the relative humidity
 * measurement
 * @return              0 if the command was successful, else an error code.
 */
int16_t sht4x_read(int32_t* temperature, int32_t* humidity);

/**
 * Enable or disable the SHT's low power mode
 *
 * @param enable_low_power_mode 1 to enable low power mode, 0 to disable
 */
void sht4x_enable_low_power_mode(uint8_t enable_low_power_mode);

/**
 * Read out the serial number
 *
 * @param serial    the address for the result of the serial number
 * @return          0 if the command was successful, else an error code.
 */
int16_t sht4x_read_serial(uint32_t* serial);

/**
 * Return the driver version
 *
 * @return Driver version string
 */
const char* sht4x_get_driver_version(void);

/**
 * Returns the configured SHT4x address.
 *
 * @return SHT4x_ADDRESS
 */
uint8_t sht4x_get_configured_address(void);


int8_t bsp_Sht4xInit(void);
int8_t bsp_Sht4xReadTempAndHumi(sht4xValTypeDef_t *pSht4xVal);

#ifdef __cplusplus
}
#endif

#endif /* SHT4X_H */
